#include "../include/dynamic_array.h"
#include "../include/read_json.h"

int dynamic_array_init(dynamic_array_t* dynamic_array, unsigned int mem_size, unsigned char max_dimension, unsigned int dimension_one_max, ...)
{
    va_list p_args;
    unsigned int calc_mem_size = 0;
    unsigned int malloc_mem_size = 0;
    if (NULL == (dynamic_array->dimension = RJ_ZALLOC(max_dimension * sizeof(unsigned int)))) {
        return -1;
    }
    // 至少是一维数组
    dynamic_array->dimension[0] = dimension_one_max;
    calc_mem_size = dynamic_array->dimension[0];

    /****************** 取出可变参列表中的参数  ******************/
    // 获取可变参列表中第一个参数的位置
    va_start(p_args, dimension_one_max);
    // 保存取出的参数(max_dimension 决定了最大有多少参数)
    // 循环读取更高维度的参数
    for (int arg_index = 1; arg_index < max_dimension; arg_index++) {
        dynamic_array->dimension[arg_index] = va_arg(p_args, int);
        if (dynamic_array->dimension[arg_index] != 0) {
            calc_mem_size *= dynamic_array->dimension[arg_index];
        }
    }
    va_end(p_args);

    /****************** 动态数组初始化  ******************/
    malloc_mem_size = calc_mem_size > mem_size ? calc_mem_size : mem_size;
    if (NULL == (dynamic_array->mem_start = RJ_ZALLOC(malloc_mem_size))) {
        RJ_FREE(dynamic_array->dimension);
        return -1;
    }
    dynamic_array->mem_end          = dynamic_array->mem_start + malloc_mem_size;
    dynamic_array->now_point        = dynamic_array->mem_start;
    dynamic_array->max_dimension    = max_dimension;

    // 函数指针赋值
    dynamic_array->get_mem_size = get_mem_size;

    // 初始化完成
    dynamic_array->init_flag = 1;

    return 0;
}

void dynamic_array_free(dynamic_array_t* dynamic_array)
{
    if (dynamic_array->init_flag) {
        RJ_FREE(dynamic_array->mem_start);
        RJ_FREE(dynamic_array->dimension);
        dynamic_array->mem_start        = NULL;
        dynamic_array->mem_end          = NULL;
        dynamic_array->now_point        = NULL;
        dynamic_array->max_dimension    = 0;
        dynamic_array->dimension        = NULL;
        dynamic_array->get_mem_size     = NULL;
        dynamic_array->init_flag        = 0;
    }
}

int print_dynamic_info(dynamic_array_t* dynamic_array)
{
    if(dynamic_array != NULL) {
        RJ_LOG_INFO("dynamic_array->mem_size:%d\n", dynamic_array->get_mem_size(dynamic_array));
        RJ_LOG_INFO("dynamic_array->max_dimension:%d\n", dynamic_array->max_dimension);
        for(int i = 0; i < dynamic_array->max_dimension; i++) {
            RJ_LOG_INFO("dynamic_array->dimension[%d] upper limit:%d\n", i, dynamic_array->dimension[i]);
        }
        return 0;
    }
    else {
        return -1;
    }
}

unsigned int get_mem_size(dynamic_array_t* dynamic_array)
{
    if (NULL != dynamic_array) {
        return dynamic_array->mem_end - dynamic_array->mem_start;
    }
    else {
        return 0;
    }
}

